package com.neulogistics.infrastructure.common.token;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Map;

@Slf4j
public class JwtTokenUtil {

    // 盐值
    private static final String SALT = "BLACKTO";
    // access_token 请求头名称
    public static final String ACCESS_HEADER = "access-token";
    // access_token 有效时间 2h
    private static final long ACCESS_TOKEN_EXP = 1000*60*60*2;
    // refresh_token 请求头名称
    public static final String REFRESH_HEADER = "refresh-token";
    // refresh_token 有效时间 7天
    private static final long REFRESH_TOKEN_EXP = 1000*60*60*24*7;
    // 过期时间键
    private static final String EXPIRE_TIME_KEY = "expire-time";
    // refresh_token key前缀
    public static final String REFRESH_TOKEN_KEY_PREFIX = "auth:token:refresh:user:";
    // refresh_token 生成器key前缀
    public static final String REFRESH_TOKEN_ICR_KEY_PREFIX = "auth:token:refresh:icr:";

    /**
     * 签发/生成token
     */
    public static String generateAccessToken(LoginUser loginUser) {
        Map<String, Object> payload = BeanUtil.beanToMap(loginUser);
        //每个jwt都默认生成一个到期时间
        payload.put(EXPIRE_TIME_KEY, DateUtil.current() + ACCESS_TOKEN_EXP);
        //生成私钥
        JWTSigner jwtSigner = JWTSignerUtil.hs256(SALT.getBytes(StandardCharsets.UTF_8));
        //生成token
        return JWTUtil.createToken(payload,jwtSigner);
    }

    public static String getRefreshTokenKey(Integer userId){
        return REFRESH_TOKEN_KEY_PREFIX + userId;
    }

    /**
     * 解析jwt
     * @param token
     * @return
     */
    public static JSONObject parse(String token){
        return JWTUtil.parseToken(token).getPayload().getClaimsJson();
    }

    /**
     * 校验token是否正确
     * @param token
     * @return
     */
    public static boolean verifyToken(String token){
        return JWTUtil.verify(token, SALT.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 校验token是否过期
     * @param token
     * @return
     */
    public static boolean isTokenInTime(String token){
        return DateUtil.current() < getExpiredToken(token);
    }

    /**
     * 获取token过期时间
     * @param token
     * @return
     */
    public static long getExpiredToken(String token){
        return Long.parseLong(parse(token).get(EXPIRE_TIME_KEY).toString());
    }
}